package com.xdf.whiteaccount.service.impl;

import com.xdf.whiteaccount.dto.PlanDTO;
import com.xdf.whiteaccount.entity.Plan;
import com.xdf.whiteaccount.entity.PlanBatchnum;
import com.xdf.whiteaccount.service.PlanBatchnumService;
import com.xdf.whiteaccount.service.PlanDTOService;
import com.xdf.whiteaccount.service.PlanService;
import com.xdf.whiteaccount.utils.Example;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @program: white-account
 * @description:
 * @author: 张柯
 * @create: 2021-07-19 09:39
 **/
@Service
@Slf4j
public class PlanDTOServiceImpl implements PlanDTOService {
    private PlanService planService;
    private PlanBatchnumService planBatchnumService;

    @Autowired
    public void setPlanService(PlanService planService) {
        this.planService = planService;
    }

    @Autowired
    public void setPlanBatchnumService(PlanBatchnumService planBatchnumService) {
        this.planBatchnumService = planBatchnumService;
    }

    /**
     * 新增计划
     *
     * @param record
     * @return
     * @throws Exception
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public PlanDTO insertSelective(PlanDTO record) throws Exception {
        planService.insertSelective(record.getPlan());
        String planCode = record.getPlan().getPlanCode();
        if (CollectionUtils.isNotEmpty(record.getDetail())) {
            //  赋值
            record.getDetail().forEach(item -> {
                item.setPlanCode(planCode);
            });
            planBatchnumService.multiInsert(record.getDetail());
        }
        return record;
    }

    /**
     * 修改计划
     *
     * @param record
     * @return
     * @throws Exception
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public PlanDTO updateSelective(PlanDTO record) throws Exception {
        planService.updateByPrimaryKeySelective(record.getPlan());
        List<PlanBatchnum> detail = planBatchnumService.listQuery(PlanBatchnum.builder().planCode(record.getPlan().getPlanCode()).build());
        List<PlanBatchnum> newly = record.getDetail();
        if (!isSameItem(detail, newly)) {
            //  删除
            if (CollectionUtils.isNotEmpty(detail))
                planBatchnumService.deleteByExample(new Example().andIn("id", detail.stream().map(PlanBatchnum::getId).toArray()));
            //  批量新增
            if (CollectionUtils.isNotEmpty(newly)) {
                newly.forEach(item -> item.setPlanCode(record.getPlan().getPlanCode()));
                newly.forEach(item -> item.setGreyfabricDate(record.getPlan().getGreyfabricDate()));
                newly.forEach(item -> item.setSubmitDate(record.getPlan().getSubmitDate()));
                newly.forEach(item -> item.setPlanDate(record.getPlan().getCreateTime()));
                planBatchnumService.multiInsert(newly);
            }
        }
        return record;
    }

    /**
     * 查询计划
     *
     * @param id 主键
     * @return
     * @throws Exception
     */
    @Override
    public PlanDTO selectByPrimaryKey(Long id) throws Exception {
        if (id == null) return null;
        PlanDTO record = new PlanDTO();
        Plan plan = planService.selectByPrimaryKey(id);
        String planCode = Optional.ofNullable(plan).map(Plan::getPlanCode).orElse("");
        record.setPlan(plan);
        record.setDetail(planBatchnumService.listQuery(PlanBatchnum.builder().planCode(planCode).build()));
        return record;
    }

    private boolean isSameItem(List<PlanBatchnum> prev, List<PlanBatchnum> curr) {
        if (CollectionUtils.isEmpty(prev) && CollectionUtils.isEmpty(curr)) return true;
        if (CollectionUtils.isEmpty(prev) || CollectionUtils.isEmpty(curr)) return false;
        if (prev.size() == curr.size()) {
            Set<String> prevBatchNum = prev.stream().map(PlanBatchnum::getBatchNum).collect(Collectors.toSet());
            Set<String> currBatchNum = curr.stream().map(PlanBatchnum::getBatchNum).collect(Collectors.toSet());
            if (prevBatchNum.size() != currBatchNum.size()) return false;
            for (String i : prevBatchNum) {
                if (!currBatchNum.contains(i)) {
                    return false;
                }
            }
            return true;
        }
        return false;
    }
}